//
//  FQXmppTool.m
//  WeChat
//
//  Created by 方桥 on 16/5/13.
//  Copyright © 2016年 方桥. All rights reserved.
//

#import "FQXmppTool.h"


@interface FQXmppTool ()<XMPPStreamDelegate>
{

    XMPPResultBlock _resultBlock;//结果回调Block

}
/**
 *  1.初始化XMPPStream
 */
-(void)setupStream;

/**
 *  2.连接服务器(传一个jid)
 */
-(void)connectToHost;

/**
 *  3.连接成功，接着发送密码
 */
-(void)sendPwdToHost;

/**
 *  4.发送一个 "在线消息" 给服务器
 */
-(void)sendOnline;
/**
 *  5.发送 “离线” 消息
 */
-(void)sendOffline;
@end
@implementation FQXmppTool
singleton_implementation(FQXmppTool)

#pragma mark -私有方法
-(void)setupStream{
    // 创建XMPPStream对象
    _xmppStream = [[XMPPStream alloc] init];
    // 添加XMPP模块
    // 1.添加电子名片模块
    _vCardStorage = [XMPPvCardCoreDataStorage sharedInstance];
    _vCard = [[XMPPvCardTempModule alloc]initWithvCardStorage:_vCardStorage];
    // 激活
    [_vCard activate:_xmppStream];
    
    // 电子名片模块还会配置 "头像模块" 一起使用
    // 2.添加 头像模块
    _avatar = [[XMPPvCardAvatarModule alloc]initWithvCardTempModule:_vCard];
    [_avatar activate:_xmppStream];
    
    
    //3.添加花名册模块
    _rosterStorage = [[XMPPRosterCoreDataStorage alloc]init];
    _roster = [[XMPPRoster alloc]initWithRosterStorage:_rosterStorage];
    [_roster activate:_xmppStream];
    
    //4.添加消息模块
    _msgArchivingStorage = [[XMPPMessageArchivingCoreDataStorage alloc]init];
    _msgArchiving = [[XMPPMessageArchiving alloc]initWithMessageArchivingStorage:_msgArchivingStorage];
    [_msgArchiving activate:_xmppStream];
    // 设置代理 -
    //#warnning 所有的代理方法都将在子线程被调用
    [_xmppStream addDelegate:self delegateQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)];
    //FQLog(@"%@",NSHomeDirectory());
}
#pragma mark - 清空资源
-(void)teardownStream
{
    //移除代理
    [_xmppStream removeDelegate:self];
    //取消模块
    [_avatar deactivate];
    [_vCard deactivate];
    [_roster deactivate];
    [_msgArchiving deactivate];
    //断开连接
    [_xmppStream disconnect];
    //清空资源
    _roster = nil;
    _rosterStorage = nil;
    _vCard = nil;
    _vCardStorage = nil;
    _avatar = nil;
    _xmppStream = nil;
    _msgArchiving = nil;
    _msgArchivingStorage = nil;
    
}

-(void)connectToHost{
    
    if (!_xmppStream) {
        [self setupStream];
    }
    XMPPJID *myJid = nil;
    FQAccount *account = [FQAccount shareAccount];
    if (self.isRegisterOperation) {//注册连接
        NSString *registerUser = account.registerUser;
        myJid = [XMPPJID jidWithUser:registerUser domain:account.domain resource:nil];
    }else{//登录连接
        // 1.设置登录用户的jid
        NSString *user = account.user;
        myJid = [XMPPJID jidWithUser:user domain:account.domain resource:nil];
    }

    _xmppStream.myJID = myJid;
    
    // 2.设置主机地址
    _xmppStream.hostName = account.host;
    
    // 3.设置主机端口号 (默认就是5222，可以不用设置)
    _xmppStream.hostPort = account.port;
    
    // 4.发起连接
    NSError *error = nil;
    // 缺少必要的参数时就会发起连接失败 ? 没有设置jid
    [_xmppStream connectWithTimeout:XMPPStreamTimeoutNone error:&error];
    if (error) {
        FQLog(@"%@",error);
    }else{
        FQLog(@"发起连接成功");
    }
    
}


-(void)sendPwdToHost{
    NSError *error = nil;
    NSString *pwd = [FQAccount shareAccount].pwd;
    [_xmppStream authenticateWithPassword:pwd error:&error];
    if (error) {
        FQLog(@"%@",error);
    }
}


-(void)sendOnline{
    //XMPP框架，已经把所有的指令封闭成对象
    XMPPPresence *presence = [XMPPPresence presence];
    FQLog(@"%@",presence);
    [_xmppStream sendElement:presence];
}
-(void)sendOffline
{
    XMPPPresence *offline = [XMPPPresence presenceWithType:@"unavailable"];
    [_xmppStream sendElement:offline];
    
}
#pragma mark -XMPPStream的代理
#pragma mark 连接建立成功
-(void)xmppStreamDidConnect:(XMPPStream *)sender{
    FQLog(@"连接建立成功");
    if (self.isRegisterOperation) {//是注册连接
        NSError *error = nil;
        
        [_xmppStream registerWithPassword:[FQAccount shareAccount].registerPwd error:&error];
    }else{//是登录连接
        [self sendPwdToHost];
    }
    
}
#pragma mark 与服务器断开连接
-(void)xmppStreamDidDisconnect:(XMPPStream *)sender withError:(NSError *)error
{
    FQLog(@"与服务器断开连接");
}
#pragma mark 登录成功
-(void)xmppStreamDidAuthenticate:(XMPPStream *)sender{
    FQLog(@"登录成功");
    [self sendOnline];
    
    //回调resultBlock
    if (_resultBlock) {
        _resultBlock(XMPPResultTypeLoginSucess);
    }
}

#pragma mark 登录失败
-(void)xmppStream:(XMPPStream *)sender didNotAuthenticate:(DDXMLElement *)error{
    FQLog(@"%@",error);
    //回调resultBlock
    if (_resultBlock) {
        _resultBlock(XMPPResultTypeLoginFailure);
        _resultBlock = nil;
    }
}
#pragma mark 注册成功
-(void)xmppStreamDidRegister:(XMPPStream *)sender
{
    FQLog(@"注册成功");
    if (_resultBlock) {
        _resultBlock(XMPPResultTypeRegisterSucess);
    }
}
#pragma mark 注册失败
-(void)xmppStream:(XMPPStream *)sender didNotRegister:(DDXMLElement *)error
{
    FQLog(@"注册失败");
    if (_resultBlock) {
        _resultBlock(XMPPResultTypeRegisterFailure);
    }
}
#pragma mark -公共方法
#pragma mark 用户登录
-(void)xmppLogin:(XMPPResultBlock)resultBlock{
    //断开以前的连接
    [_xmppStream disconnect];
    
    // 保存resultBlock
    _resultBlock = resultBlock;
    
    // 连接服务器开始登录的操作
    [self connectToHost];
    
}
#pragma mark 用户注册
-(void)xmppRegister:(XMPPResultBlock)resultBlock
{
    //断开以前的连接
    [_xmppStream disconnect];
    // 保存resultBlock
    _resultBlock = resultBlock;
    
    // 连接服务器开始登录的操作
    [self connectToHost];
}
#pragma mark 用户注销
-(void)xmppLogout
{
    // 1.发送 "离线消息" 给服务器
    [self sendOffline];
    // 2.断开与服务器的连接
    [_xmppStream disconnect];
}

-(void)dealloc
{
    [self teardownStream];
}
@end
